#include <asm-generic/errno-base.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <unistd.h>

struct msgbuf {
  long mtype;      /* message type, must be > 0 */
  char mtext[100]; /* message data */
};

int main(int argc, char *argv[]) {
  pid_t pid[2];
  int i;
  for (i = 0; i < 2; i++) {
    pid[i] = fork();
    if (pid[i] == 0)
      break;
  }
  if (i == 2) {
    wait(NULL);
    wait(NULL);
  }

  if (pid[0] == 0) {
    printf("son1\n");
    key_t key = ftok(".", 1);
    if (key < 0) {
      perror("ftok fail");
      exit(-1);
    }

    int msg_id = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
    if (msg_id < 0) {
      if (errno == EEXIST) {
        msg_id = msgget(key, 0666);
        if (msg_id < 0) {
          perror("msgget fail");
          exit(-1);
        }
      } else {
        perror("msgget fail");
        exit(-1);
      }
    }

    struct msgbuf buf;
    buf.mtype = 1;
    while (1) {
      printf("please input:");
      scanf("%s", buf.mtext);

      msgsnd(msg_id, &buf, sizeof(struct msgbuf), 0);
      if (!strcmp(buf.mtext, "bye"))
        break;
    }

    msgctl(msg_id, IPC_RMID, NULL);

  } else if (pid[1] == 0) {
    printf("son2\n");
    key_t key = ftok(".", 1);
    if (key < 0) {
      perror("ftok fail");
      exit(-1);
    }

    int msg_id = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
    if (msg_id < 0) {
      if (errno == EEXIST) {
        msg_id = msgget(key, 0666);
        if (msg_id < 0) {
          perror("msgget fail");
          exit(-1);
        }
      } else {
        perror("msgget fail");
        exit(-1);
      }
    }

    struct msgbuf buf;
    while (1) {
      msgrcv(msg_id,&buf,sizeof(buf),1,0);
      printf("read is %s\n", buf.mtext);
      if (!strcmp(buf.mtext, "bye"))
        break;
    }

    msgctl(msg_id, IPC_RMID, NULL);
  }

  return 0;
}
